﻿using DocumentFormat.OpenXml.Lite.Helper;
using DocumentFormat.OpenXml.Lite.WordprocessingML.Word.Types;
using DocumentFormat.OpenXml.Lite.Xml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace DocumentFormat.OpenXml.Lite.WordprocessingML.Word.ParagraphProperties
{
    [XmlRoot("shd", Namespace = Constants.WordMain)]
    public class Shading : XmlSerializable, IParagraphPropElement, ITablePropElement, ITableCellPropElement
    {
        [XmlAttribute("val", Namespace = Constants.WordMain, Form = XmlSchemaForm.Qualified)]
        public ST_Shd Value { get; set; }

        /// <summary>
        /// Hexadecimal number. Length: 6
        /// </summary>
        [Optional]
        [XmlAttribute("color", Namespace = Constants.WordMain, Form = XmlSchemaForm.Qualified)]
        public string Color
        {
            get { return color; }
            set
            {
                if (value == null || (value.Length != 6 && value != "auto") ||
                    (value.Length == 6 && !Helpers.ParseHexadecimalValue(value)))
                {
                    throw new ArgumentException("String: " + value +
                        "is not a valid hexadecimal string or length is not 6!");
                }

                color = value;
            }
        }

        [Optional]
        [XmlAttribute("themeColor", Namespace = Constants.WordMain, Form = XmlSchemaForm.Qualified)]
        public Nullable<ST_ThemeColor> ThemeColor { get; set; }

        /// <summary>
        /// Hexadecimal number. Length: 2
        /// </summary>
        [Optional]
        [XmlAttribute("themeTint", Namespace = Constants.WordMain, Form = XmlSchemaForm.Qualified)]
        public string ThemeColorTint
        {
            get { return themeColorTint; }
            set
            {
                if (value == null || value.Length != 2 || !Helpers.ParseHexadecimalValue(value))
                {
                    throw new ArgumentException("String: " + value +
                        "is not a valid hexadecimal string or length is not 2!");
                }

                themeColorTint = value;
            }
        }

        /// <summary>
        /// Hexadecimal number. Length: 2
        /// </summary>
        [Optional]
        [XmlAttribute("themeShade", Namespace = Constants.WordMain, Form = XmlSchemaForm.Qualified)]
        public string ThemeColorShade
        {
            get { return themeColorShade; }
            set
            {
                if (value == null || value.Length != 2 || !Helpers.ParseHexadecimalValue(value))
                {
                    throw new ArgumentException("String: " + value +
                        "is not a valid hexadecimal string or length is not 2!");
                }

                themeColorShade = value;
            }
        }

        /// <summary>
        /// Hexadecimal number. Length: 6
        /// </summary>
        [Optional]
        [XmlAttribute("fill", Namespace = Constants.WordMain, Form = XmlSchemaForm.Qualified)]
        public string BackgroundColor
        {
            get { return backColor; }
            set
            {
                if (value == null || (value.Length != 6 && value != "auto") ||
                    (value.Length == 6 && !Helpers.ParseHexadecimalValue(value)))
                {
                    throw new ArgumentException("String: " + value +
                        "is not a valid hexadecimal string or length is not 6!");
                }

                backColor = value;
            }
        }

        [Optional]
        [XmlAttribute("themeFill", Namespace = Constants.WordMain, Form = XmlSchemaForm.Qualified)]
        public Nullable<ST_ThemeColor> BackgroundThemeColor { get; set; }

        /// <summary>
        /// Hexadecimal number. Length: 2
        /// </summary>
        [Optional]
        [XmlAttribute("themeFillTint", Namespace = Constants.WordMain, Form = XmlSchemaForm.Qualified)]
        public string BackgroundThemeColorTint
        {
            get { return backThemeColorTint; }
            set
            {
                if (value == null || value.Length != 2 || !Helpers.ParseHexadecimalValue(value))
                {
                    throw new ArgumentException("String: " + value +
                        "is not a valid hexadecimal string or length is not 2!");
                }

                backThemeColorTint = value;
            }
        }

        /// <summary>
        /// Hexadecimal number. Length: 2
        /// </summary>
        [Optional]
        [XmlAttribute("themeFillShade", Namespace = Constants.WordMain, Form = XmlSchemaForm.Qualified)]
        public string BackgroundThemeColorShade
        {
            get { return backThemeColorShade; }
            set
            {
                if (value == null || value.Length != 2 || !Helpers.ParseHexadecimalValue(value))
                {
                    throw new ArgumentException("String: " + value +
                        "is not a valid hexadecimal string or length is not 2!");
                }

                backThemeColorShade = value;
            }
        }

        [XmlIgnore]
        private string color;

        [XmlIgnore]
        private string themeColorTint;

        [XmlIgnore]
        private string themeColorShade;

        [XmlIgnore]
        private string backColor;

        [XmlIgnore]
        private string backThemeColorTint;

        [XmlIgnore]
        private string backThemeColorShade;

        public Shading() { }

        public void Copy(object obj)
        {
            if (obj is Shading)
            {
                this.Value = (obj as Shading).Value;

                if ((obj as Shading).Color != null)
                    this.Color = (obj as Shading).Color;
                if ((obj as Shading).ThemeColor != null)
                    this.ThemeColor = (obj as Shading).ThemeColor;
                if ((obj as Shading).ThemeColorTint != null)
                    this.ThemeColorTint = (obj as Shading).ThemeColorTint;
                if ((obj as Shading).ThemeColorShade != null)
                    this.ThemeColorShade = (obj as Shading).ThemeColorShade;

                if ((obj as Shading).BackgroundColor != null)
                    this.BackgroundColor = (obj as Shading).BackgroundColor;
                if ((obj as Shading).BackgroundThemeColor != null)
                    this.BackgroundThemeColor = (obj as Shading).BackgroundThemeColor;
                if ((obj as Shading).BackgroundThemeColorTint != null)
                    this.BackgroundThemeColorTint = (obj as Shading).BackgroundThemeColorTint;
                if ((obj as Shading).BackgroundThemeColorShade != null)
                    this.BackgroundThemeColorShade = (obj as Shading).BackgroundThemeColorShade;
            }
        }
    }
}
